home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / System Utility / Cache Control / No Cache / cache.c next >
C/C++ Source or Header  |  1992-01-20  |  7KB  |  188 lines

  1. /* No Cache © 1991 by Tom Thompson, for Overpriced Software. All world rights reserved. */
  2. /*  No Cache enables/disables the 68040's on-chip caches on the fly on the Mac Quadras. */
  3. /*  It does this by simply hammering at the cache control register. Since the Mac OS */
  4. /*  typically runs in the Supervisor mode, we can get away with using such privileged */
  5. /*  instructions. Doesn't work under virtual memory, because then OS runs in User mode. */
  6. /*  VM driver runs in Supervisor mode to do page faulting. */
  7.  
  8. #include <Types.h>
  9. #include <asm.h>
  10. #include <pascal.h>
  11. #include <QuickDraw.h>
  12. #include <Windows.h>
  13. #include <Fonts.h>
  14. #include <Dialogs.h>
  15. #include <Menus.h>
  16. #include <Events.h>
  17. #include <OSEvents.h>
  18. #include <OSUtils.h>
  19. #include <Packages.h>
  20. #include <Timer.h>
  21.  
  22. #include <THINK.h>
  23.  
  24. #define BUTTON_OFF             0
  25. #define BUTTON_ON              1
  26. #define CACHE_DIALOG_ID      400
  27. #define DISABLE_CACHE          2
  28. #define ENABLE_CACHE           3
  29. #define NIL                    0L
  30. #define ON_MASK       0x80008000L    /* Mask to extract 68040's cache control bits */
  31. #define ON            0x80008000L    /* Both caches are on (bits set) */
  32.  
  33. #define MC68040                5
  34.  
  35. #define TOP                   40
  36. #define LEFT                  40
  37. #define BOTTOM               160
  38. #define RIGHT                470
  39.  
  40. /* Globals */
  41. EventRecord      myEvent;
  42.  
  43. /* Our home-brew abs() function, since THINK's linker has kittens if we try to use  */
  44. /*  the ANSI library's abs() in a code resource. */
  45. long abs(long value)
  46. {
  47.   if (value < 0)
  48.     return (-value);
  49.   else
  50.     return value;
  51. } /* end abs() */
  52.  
  53. /* Procedure to see if Mac has a 68040. We bail out quick to prevent trouble if */
  54. /*   it doesn't */
  55. Boolean Check_System(void)
  56. {
  57. OSErr          error;                               /* Status of the SysEnvirons trap */
  58. SysEnvRec      machineInfo;                        /* Record with machine-specific data */
  59. DialogPtr      checkDialog;
  60. short          itemhit;
  61. unsigned char  message[51] = "\P Sorry, No Cache only works with 68040-based Macs.";
  62.  
  63. int         cpuType;                              /* Local variables to hold hardware info */
  64. Boolean     noTrouble;
  65. int         version_requested;                   /* Version of SysEnvirons() to use */
  66.  
  67.    noTrouble = TRUE;                                /* We're not in trouble (yet) */
  68.  
  69.    version_requested = 2;                        /* MUST set this value if you want valid results */
  70.    error = SysEnvirons(version_requested, &machineInfo); /* Get the environment we're running in */
  71.    cpuType = machineInfo.processor;           /* Extract info  */
  72.  
  73.    if (cpuType != MC68040)                         /* Got an '040? */
  74.       {                                          /* No. Sorry, can't run without it  */
  75.       ParamText(message, NIL, NIL, NIL);
  76.       checkDialog = GetNewDialog(128, NIL, (WindowPtr) -1);
  77.       ModalDialog(0L, &itemhit);
  78.       DisposDialog(checkDialog);
  79.       noTrouble = FALSE;
  80.       } /* end if !MC68040 */
  81.    return noTrouble;
  82. } /* end Check_System() */
  83.  
  84. /************* Main program *************/
  85. void main()
  86. {
  87. DialogPtr     theDialog;
  88.  
  89. short         itemHit;
  90. unsigned char cacheContents[20];
  91. unsigned long cacheRegister;
  92.  
  93. short         item, itemType;
  94. Rect          itemBox;
  95. Handle        itemHandle;
  96.  
  97. long int      centerHoriz, centerVert;       /* Screen dimensions */
  98. long int      frameHoriz, frameVert;         /* depth box dimensions */
  99. long int      globalLeft, globalTop;         /* Global coords to position our windows */
  100.  
  101. /* Make sure we've got some master pointers */
  102.    MoreMasters();
  103.    MoreMasters();
  104.    MoreMasters();
  105.  
  106. /* Set up the Mac */
  107.    InitGraf(&qd.thePort);
  108.    InitFonts();
  109.    FlushEvents(everyEvent, 0);
  110.    InitWindows();
  111.    InitMenus();
  112.    TEInit();
  113.    InitDialogs(0L);
  114.    InitCursor();
  115.  
  116.    if(Check_System() == TRUE)
  117.      {
  118.  
  119. /* Computations to center a window */
  120.       centerHoriz = abs(qd.screenBits.bounds.right - qd.screenBits.bounds.left) / 2;
  121.       centerVert = abs(qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) / 2;    
  122.       frameHoriz = centerHoriz - ((RIGHT - LEFT) / 2);  /* Calculate offsets from screen center */
  123.       frameVert  = centerVert - ((BOTTOM - TOP) / 2);
  124.       globalLeft = qd.screenBits.bounds.left + frameHoriz;    /* Add back into screen coords to get.. */
  125.       globalTop = qd.screenBits.bounds.top + frameVert;       /*   ...global coords on GrayRgn */
  126.  
  127. /* Set up a window */
  128.     theDialog = GetNewDialog(CACHE_DIALOG_ID, 0L, (WindowPtr) -1L);
  129.     MoveWindow(theDialog, globalLeft, globalTop, TRUE);  /* Move it to screen's center */
  130.  
  131.    asm 68030{
  132.        MOVEC  CACR, D0             ;Copy cache control register
  133.        MOVE.L D0, cacheRegister    ;Save copy in our variable
  134.        }  /* end asm */
  135.  
  136. /* Debug stuff */
  137. /*  NumToString(cacheRegister, cacheContents);
  138.   ParamText(cacheContents, NIL, NIL, NIL); */
  139.  
  140. /* Set up rest of dialog's controls */  
  141.     if ((cacheRegister & ON_MASK) == ON)   /* 68040 caches enabled? */
  142.        {                                   /* Yep, highlight dialog's ON button */
  143.        GetDItem(theDialog, ENABLE_CACHE, &itemType, &itemHandle, &itemBox);  /* Get our item */
  144.        SetCtlValue((ControlHandle) itemHandle, BUTTON_ON);  /* Yes, turn button on */
  145.        GetDItem(theDialog, DISABLE_CACHE, &itemType, &itemHandle, &itemBox);
  146.        SetCtlValue((ControlHandle) itemHandle, BUTTON_OFF);  /* Turn button off */
  147.        } /* end if == ON */
  148.      else                                  /* Nope. They're off, highlight off button */
  149.       {
  150.        GetDItem(theDialog, DISABLE_CACHE, &itemType, &itemHandle, &itemBox);
  151.        SetCtlValue((ControlHandle) itemHandle, BUTTON_ON);
  152.        GetDItem(theDialog, ENABLE_CACHE, &itemType, &itemHandle, &itemBox);
  153.       SetCtlValue((ControlHandle) itemHandle, BUTTON_OFF);
  154.        } /* end else */
  155.     ShowWindow(theDialog);                /* Make the window visible */
  156.     DrawDialog(theDialog);                /* Now show our modified controls */
  157.  
  158. /* Handle events. Loop on bogus stuff, act on a valid item hit value. */
  159.     do
  160.       {
  161.       ModalDialog(0L, &itemHit);  
  162.       switch (itemHit)
  163.         {
  164.         case ENABLE_CACHE:                /* itemHit = 1 */
  165.         asm 68030{
  166.           MOVE.L #ON, D0
  167.           MOVEC  D0, CACR                 /* Stuff bits into control reg. to turn caches on */
  168.           } /* end asm */
  169.           ;
  170.         break;
  171.         case DISABLE_CACHE:               /* itemHit  = 2 */
  172.         asm 68030{                        /* Note that we have to generate the raw opcode ourselves */
  173.           DC.W  0xF4F8                    ;CPUSHA BC  -- Flush both caches
  174.           MOVEQ #0, D0
  175.           MOVEC D0, CACR                  /* Clear all bits in cache reg. to turn caches off */
  176.           } /* end asm */
  177.           ;
  178.         break;
  179.         default:                          /* Not a valid item, do nothing */
  180.         break;
  181.         } /* end switch */
  182.      } /* end do */
  183.      while ((itemHit < ENABLE_CACHE) && (itemHit > DISABLE_CACHE));
  184.      DisposDialog(theDialog);
  185.    } /*  end if Check_System() */
  186.     
  187.  } /* end main */
  188.